package com.h2cloud;

import lombok.extern.log4j.Log4j2;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author: wulongkai
 * @create: 2022-08-22 23:49
 **/

@Log4j2
class CustomThreadPoolExecutor extends ThreadPoolExecutor {

    public CustomThreadPoolExecutor() {
        super(10, 10, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000));
    }

    protected void afterExecute(Runnable r, Throwable t) {
        log.info("inter afterExecute...");
//        try {
//            Thread.sleep(5000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        super.afterExecute(r, t);
        if (t == null && r instanceof Future<?>) {
            try {
                Object result = ((Future<?>) r).get();
                log.info("result:{}", result);
            } catch (CancellationException ce) {
                t = ce;
            } catch (ExecutionException ee) {
                t = ee.getCause();
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt(); // ignore/reset
            }
        }
        if (t != null) {
            log.info("afterExecute，has error");
            t.printStackTrace();
        }
    }
}

@Log4j2
public class CustomThreadPoolExecutorDemo {

    public static void main(String args[]) {
        log.info("create service");
        CustomThreadPoolExecutor service = new CustomThreadPoolExecutor();
        List<Future<?>> list = new ArrayList<>();
        for (int i = 0; i < 15; i++) {
            Future<?> submit = service.submit(() -> {
                int a = 4, b = 0;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.info("a and b=" + a + ":" + b);
//            System.out.println("a/b:" + (a / b));
                service.submit(() -> {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    log.info("sub runnable...");
                });
                log.info("Thread Name in Runnable after divide by zero:" + Thread.currentThread().getName());
            });
            list.add(submit);
        }


        log.info("submit.get() wait start");
        list.forEach(f -> {
            try {
                f.get();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        log.info("submit.get() wait end");
        service.shutdown();
    }
}
